﻿using System.Collections.Generic;
using Engine;
using Engine.Graphics;
using Game;
using Mekiasm.Common;


namespace Mekiasm
{
    public class ItemSystem
    {
        public static DrawBlockEnvironmentData m_drawBlockEnvironmentData = new DrawBlockEnvironmentData();
        public static PrimitivesRenderer3D m_primitivesRenderer = new PrimitivesRenderer3D();
        public static List<Common.ItemElement> Elements = new List<Common.ItemElement>();
        public static void Add(Common.ItemElement Element)
        {
            if (Elements.Find(p => p.Point == Element.Point) == null)
            {
                Elements.Add(Element);
                UpdateConnection(Element.Point);
            }
        }
        public static Common.ItemElement Get(Point3 point3)
        {
            return Elements.Find(p => p.Point == point3);
        }
        public static void UpdateConnection(Point3 pointStart)
        {
            ClearFlags();
            updateConnectionsLogic(pointStart);
        }
        public static void updateConnectionsLogic(Point3 pointStart)
        {
            Common.ItemElement StartElement = Elements.Find(p => p.Point == pointStart);
            if (StartElement == null || StartElement.Visited) return;
            StartElement.Visited = true;
            StartElement.Connections.Clear();
            for (int i = 0; i < 6; i++)
            {
                Point3 point3 = pointStart + CellFace.FaceToPoint3(i);
                Common.ItemElement neibor = Elements.Find(p => p.Point == point3);
                if (neibor != null)
                {
                    StartElement.Connections.Add(neibor);
                }
                updateConnectionsLogic(point3);
            }
        }
        public static void ClearFlags()
        {
            for (int i = 0; i < Elements.Count; i++)
            {
                Elements[i].Visited = false;
            }
        }
        public static void Remove(int x, int y, int z)
        {
            Point3 point3 = new Point3(x, y, z);
            Common.ItemElement element = Elements.Find(p => p.Point == point3);
            if (element != null)
            {
                if (element.Component.Value.HasValue)
                {
                    ILibrary.SubsystemPickables.AddPickable(element.Component.Value.Value, 1, element.Position, element.Component.Velocity, null);
                }
                Elements.Remove(element);
                for (int i = 0; i < Elements.Count; i++)
                {
                    var element1 = Elements[i].Connections.Find(p => p.Point == point3);
                    if (element1 != null)
                    {
                        var neiborComponent = element1.Instance.Machine as ComponentItemEnergyMachine;
                        if (neiborComponent.Value.HasValue)
                        {
                            ILibrary.SubsystemPickables.AddPickable(neiborComponent.Value.Value, 1, element1.Position, neiborComponent.Velocity, null);
                        }
                        Elements[i].Connections.Remove(element1);
                    }
                }
            }
            UpdateConnection(point3);
        }
        public static void Update(float dt)
        {
            for (int i = 0; i < Elements.Count; i++)
            {
                Elements[i].Simulate();
            }
        }
        public static void Draw(Camera camera)
        {
            for (int i = 0; i < Elements.Count; i++)
            {
                ComponentItemEnergyMachine component = Elements[i].Component;
                if (component.Value.HasValue)
                {
                    double totalElapsedGameTime = ILibrary.SubsystemGameInfo.TotalElapsedGameTime;
                    Matrix matrix = Matrix.CreateRotationY((float)MathUtils.Remainder(totalElapsedGameTime, 6.2831854820251465));
                    matrix *= Matrix.CreateScale(0.5f);
                    Vector3 position = component.NowPosition + new Vector3(0.5f);
                    int num3 = Terrain.ExtractContents(component.Value.Value);
                    Block block = BlocksManager.Blocks[num3];
                    m_drawBlockEnvironmentData.SubsystemTerrain = ILibrary.SubsystemTerrain;
                    m_drawBlockEnvironmentData.Light = 15;
                    m_drawBlockEnvironmentData.InWorldMatrix.Translation = position;
                    matrix.Translation = position;
                    block.DrawBlock(m_primitivesRenderer, component.Value.Value, Color.White, 0.3f, ref matrix, m_drawBlockEnvironmentData);
                    m_primitivesRenderer.Flush(camera.ViewProjectionMatrix);
                }
            }
        }
        public static void Dispose()
        {
            Elements.Clear();
        }
    }
}
